package app

import (
	"common/config"
	"common/discovery"
	"common/logs"
	"context"
	"core/repository"
	"google.golang.org/grpc"
	"net"
	"os"
	"os/signal"
	"syscall"
	"user/internal/service"
	"user/pb"
)

// Run 服务启动
func Run(ctx context.Context) error {
	// 1. 创建 gRPC 服务、 Etcd 服务、数据库服务
	server := grpc.NewServer()
	register := discovery.NewEtcdRegister()
	dbManager := repository.New()
	go func() {
		// 2. 启动一个 TCP 服务
		listen, err := net.Listen("tcp", config.Conf.Grpc.Addr)
		if err != nil {
			logs.Fatal("user grpc server listen error：%v", err)
		}
		// 3. 将服务注册到注册中心
		if err = register.ServerRegister(config.Conf.Etcd); err != nil {
			logs.Fatal("server register error：%v.Please check the etcd service.", err)
		}
		// 4. 注册服务
		pb.RegisterUserServiceServer(server, service.NewAccountService(dbManager))
		// 5. 启动 gRPC 服务
		if err = server.Serve(listen); err != nil {
			logs.Fatal("user grpc server run failed：%v", err)
		}
	}()
	stop := func() {
		server.Stop()
		register.Close()
		dbManager.Close()
		logs.Info("stop app finish.")
	}
	// 3. 优雅启停
	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT, syscall.SIGHUP)
	select {
	case <-ctx.Done():
		stop()
	case s := <-c:
		switch s {
		case syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT:
			stop()
			logs.Warn("user app quit.")
		case syscall.SIGHUP:
			stop()
			logs.Warn("hang up!! user app quit.")
		}
	}
	return nil
}
